﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.AgentVisuals
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using System;
using TaleWorlds.Core;
using TaleWorlds.DotNet;
using TaleWorlds.Engine;
using TaleWorlds.Library;
using TaleWorlds.ObjectSystem;

#nullable disable
namespace TaleWorlds.MountAndBlade.View
{
  public class AgentVisuals : IAgentVisual
  {
    public const float RandomGlossinessRange = 0.05f;
    public const float RandomClothingColor1HueRange = 4f;
    public const float RandomClothingColor1SaturationRange = 0.2f;
    public const float RandomClothingColor1BrightnessRange = 0.2f;
    public const float RandomClothingColor2HueRange = 8f;
    public const float RandomClothingColor2SaturationRange = 0.5f;
    public const float RandomClothingColor2BrightnessRange = 0.3f;
    private static readonly ActionIndexCache act_command_leftstance_cached = ActionIndexCache.Create("act_command_leftstance");
    private AgentVisualsData _data;
    private float _scale;

    public bool IsFemale
    {
      get
      {
        return this._data.SkeletonTypeData == SkeletonType.Female || this._data.SkeletonTypeData == SkeletonType.KidFemale1 || this._data.SkeletonTypeData == SkeletonType.KidFemale2 || this._data.SkeletonTypeData == SkeletonType.KidFemale3;
      }
    }

    public MBAgentVisuals GetVisuals() => this._data.AgentVisuals;

    public void Reset() => this._data.AgentVisuals.Reset();

    public void ResetNextFrame() => this._data.AgentVisuals.ResetNextFrame();

    public MatrixFrame GetFrame() => this._data.FrameData;

    public BodyProperties GetBodyProperties() => this._data.BodyPropertiesData;

    public void SetBodyProperties(BodyProperties bodyProperties)
    {
      this._data.BodyProperties(bodyProperties);
    }

    public bool GetIsFemale() => this.IsFemale;

    public string GetCharacterObjectID() => this._data.CharacterObjectStringIdData;

    public void SetCharacterObjectID(string id) => this._data.CharacterObjectStringId(id);

    public Equipment GetEquipment() => this._data.EquipmentData;

    private AgentVisuals(
      AgentVisualsData data,
      string name,
      bool isRandomProgress,
      bool needBatchedVersionForWeaponMeshes,
      bool forceUseFaceCache)
    {
      this._data = data;
      this._data.AgentVisuals = MBAgentVisuals.CreateAgentVisuals(this._data.SceneData, name, data.MonsterData.EyeOffsetWrtHead);
      if ((NativeObject) data.EntityData != (NativeObject) null)
        this._data.AgentVisuals.SetEntity(data.EntityData);
      this._scale = (double) this._data.ScaleData <= 9.9999997473787516E-06 ? 1f : this._data.ScaleData;
      this.Refresh(needBatchedVersionForWeaponMeshes, isRandomProgress: isRandomProgress, forceUseFaceCache: forceUseFaceCache);
    }

    public AgentVisualsData GetCopyAgentVisualsData() => new AgentVisualsData(this._data);

    public GameEntity GetEntity() => this._data.AgentVisuals.GetEntity();

    public void SetVisible(bool value) => this._data.AgentVisuals.SetVisible(value);

    public Vec3 GetGlobalStableEyePoint(bool isHumanoid)
    {
      return this._data.AgentVisuals.GetGlobalStableEyePoint(isHumanoid);
    }

    public Vec3 GetGlobalStableNeckPoint(bool isHumanoid)
    {
      return this._data.AgentVisuals.GetGlobalStableNeckPoint(isHumanoid);
    }

    public CompositeComponent AddPrefabToAgentVisualBoneByBoneType(
      string prefabName,
      HumanBone boneType)
    {
      return this._data.AgentVisuals.AddPrefabToAgentVisualBoneByBoneType(prefabName, boneType);
    }

    public CompositeComponent AddPrefabToAgentVisualBoneByRealBoneIndex(
      string prefabName,
      sbyte realBoneIndex)
    {
      return this._data.AgentVisuals.AddPrefabToAgentVisualBoneByRealBoneIndex(prefabName, realBoneIndex);
    }

    public void SetAgentLodZeroOrMax(bool value)
    {
      this._data.AgentVisuals.SetAgentLodZeroOrMax(value);
    }

    public float GetScale() => this._scale;

    public void SetAction(
      ActionIndexCache actionIndex,
      float startProgress = 0.0f,
      bool forceFaceMorphRestart = true)
    {
      if (!((NativeObject) this._data.AgentVisuals != (NativeObject) null))
        return;
      Skeleton skeleton = this._data.AgentVisuals.GetSkeleton();
      if (!((NativeObject) skeleton != (NativeObject) null))
        return;
      skeleton.SetAgentActionChannel(0, actionIndex, startProgress, forceFaceMorphRestart: forceFaceMorphRestart);
      skeleton.ManualInvalidate();
    }

    public bool DoesActionContinueWithCurrentAction(ActionIndexCache actionIndex)
    {
      bool flag = false;
      if ((NativeObject) this._data.AgentVisuals != (NativeObject) null)
      {
        Skeleton skeleton = this._data.AgentVisuals.GetSkeleton();
        if ((NativeObject) skeleton != (NativeObject) null)
          flag = skeleton.DoesActionContinueWithCurrentActionAtChannel(0, actionIndex);
      }
      return flag;
    }

    public float GetAnimationParameterAtChannel(int channelIndex)
    {
      float parameterAtChannel = 0.0f;
      if ((NativeObject) this._data.AgentVisuals != (NativeObject) null && (NativeObject) this._data.AgentVisuals.GetSkeleton() != (NativeObject) null)
        parameterAtChannel = this._data.AgentVisuals.GetSkeleton().GetAnimationParameterAtChannel(channelIndex);
      return parameterAtChannel;
    }

    public void Refresh(
      bool needBatchedVersionForWeaponMeshes,
      AgentVisualsData data,
      bool forceUseFaceCache = false)
    {
      AgentVisualsData data1 = this._data;
      this._data = data;
      bool removeSkeleton = data1.SkeletonTypeData != this._data.SkeletonTypeData;
      Equipment equipmentData = this._data.EquipmentData;
      this.Refresh(needBatchedVersionForWeaponMeshes, removeSkeleton, equipmentData, forceUseFaceCache: forceUseFaceCache);
    }

    public void SetClothWindToWeaponAtIndex(
      Vec3 localWindDirection,
      bool isLocal,
      EquipmentIndex weaponIndex)
    {
      this._data.AgentVisuals.SetClothWindToWeaponAtIndex(localWindDirection, isLocal, weaponIndex);
    }

    private void Refresh(
      bool needBatchedVersionForWeaponMeshes,
      bool removeSkeleton = false,
      Equipment oldEquipment = null,
      bool isRandomProgress = false,
      bool forceUseFaceCache = false)
    {
      float channelParameter = 0.0f;
      float time = 0.0f;
      string str = "";
      bool flag1 = this._data.MonsterData.Flags.HasAnyFlag<AgentFlag>(AgentFlag.IsHumanoid);
      Skeleton skeleton1 = this._data.AgentVisuals.GetSkeleton();
      float blendPeriodOverride = -0.2f;
      ActionIndexCache actionIndex;
      if ((NativeObject) skeleton1 != (NativeObject) null && this._data.ActionSetData.IsValid)
      {
        channelParameter = skeleton1.GetAnimationParameterAtChannel(0);
        actionIndex = skeleton1.GetActionAtChannel(0);
        blendPeriodOverride = 0.0f;
        if (flag1)
        {
          time = MBSkeletonExtensions.GetSkeletonFaceAnimationTime(skeleton1);
          str = MBSkeletonExtensions.GetSkeletonFaceAnimationName(skeleton1);
        }
      }
      else
        actionIndex = this._data.ActionCodeData;
      if ((NativeObject) skeleton1 != (NativeObject) null)
        skeleton1.ManualInvalidate();
      this._data.AgentVisuals.SetSetupMorphNode(this._data.UseMorphAnimsData);
      this._data.AgentVisuals.UseScaledWeapons(this._data.UseScaledWeaponsData);
      MatrixFrame frameData = this._data.FrameData;
      this._scale = (double) this._data.ScaleData == 0.0 ? MBBodyProperties.GetScaleFromKey(this._data.RaceData, this.IsFemale ? 1 : 0, this._data.BodyPropertiesData) : this._data.ScaleData;
      frameData.rotation.ApplyScaleLocal(this._scale);
      this._data.AgentVisuals.SetFrame(ref frameData);
      int num = removeSkeleton || !((NativeObject) skeleton1 != (NativeObject) null) ? 0 : (oldEquipment != null ? 1 : 0);
      bool flag2 = false;
      if (num != 0)
        flag2 = this.ClearAndAddChangedVisualComponentsOfWeapons(oldEquipment, needBatchedVersionForWeaponMeshes);
      MBActionSet actionSetData;
      if (num == 0 || !flag2)
      {
        this._data.AgentVisuals.ClearVisualComponents(false);
        actionSetData = this._data.ActionSetData;
        if (actionSetData.IsValid && str != "facegen_teeth")
        {
          AnimationSystemData animationSystemData = this._data.MonsterData.FillAnimationSystemData(this._data.ActionSetData, 1f, this._data.HasClippingPlaneData);
          Skeleton withActionSet = MBSkeletonExtensions.CreateWithActionSet(ref animationSystemData);
          this._data.AgentVisuals.SetSkeleton(withActionSet);
          withActionSet.ManualInvalidate();
        }
        if (this._data.EquipmentData == null)
          this.AddSkinMeshesToEntity(481, !needBatchedVersionForWeaponMeshes, forceUseFaceCache);
        else if (!string.IsNullOrEmpty(this._data.MountCreationKeyData) || !flag1)
          MountVisualCreator.AddMountMeshToEntity(this.GetEntity(), this._data.EquipmentData[EquipmentIndex.ArmorItemEndSlot].Item, this._data.EquipmentData[EquipmentIndex.HorseHarness].Item, this._data.MountCreationKeyData);
        else
          this.AddSkinArmorWeaponMultiMeshesToEntity(this._data.ClothColor1Data, this._data.ClothColor2Data, needBatchedVersionForWeaponMeshes, forceUseFaceCache);
      }
      actionSetData = this._data.ActionSetData;
      if (!actionSetData.IsValid || !(actionIndex != ActionIndexCache.act_none))
        return;
      if (isRandomProgress)
        channelParameter = MBRandom.RandomFloat;
      Skeleton skeleton2 = this._data.AgentVisuals.GetSkeleton();
      if (!((NativeObject) skeleton2 != (NativeObject) null))
        return;
      skeleton2.SetAgentActionChannel(0, actionIndex, channelParameter, blendPeriodOverride);
      if ((double) time > 0.0)
        MBSkeletonExtensions.SetSkeletonFaceAnimationTime(skeleton2, time);
      skeleton2.ManualInvalidate();
    }

    public void TickVisuals()
    {
      if (!this._data.ActionSetData.IsValid)
        return;
      this._data.AgentVisuals.GetSkeleton().TickActionChannels();
    }

    public void Tick(AgentVisuals parentAgentVisuals, float dt, bool isEntityMoving = false, float speed = 0.0f)
    {
      this._data.AgentVisuals.Tick(parentAgentVisuals?._data.AgentVisuals, dt, isEntityMoving, speed);
    }

    public static AgentVisuals Create(
      AgentVisualsData data,
      string name,
      bool isRandomProgress,
      bool needBatchedVersionForWeaponMeshes,
      bool forceUseFaceCache)
    {
      return new AgentVisuals(data, name, isRandomProgress, needBatchedVersionForWeaponMeshes, forceUseFaceCache);
    }

    public static float GetRandomGlossFactor(Random randomGenerator)
    {
      return (float) (1.0 + ((double) randomGenerator.NextFloat() * 2.0 - 1.0) * 0.05000000074505806);
    }

    public static void GetRandomClothingColors(
      int seed,
      Color inputColor1,
      Color inputColor2,
      out Color color1,
      out Color color2)
    {
      MBFastRandom mbFastRandom = new MBFastRandom((uint) seed);
      color1 = inputColor1.AddFactorInHSB((float) ((2.0 * (double) mbFastRandom.NextFloat() - 1.0) * 4.0), (float) ((2.0 * (double) mbFastRandom.NextFloat() - 1.0) * 0.20000000298023224), (float) ((2.0 * (double) mbFastRandom.NextFloat() - 1.0) * 0.20000000298023224));
      color2 = inputColor2.AddFactorInHSB((float) ((2.0 * (double) mbFastRandom.NextFloat() - 1.0) * 8.0), (float) ((2.0 * (double) mbFastRandom.NextFloat() - 1.0) * 0.5), (float) ((2.0 * (double) mbFastRandom.NextFloat() - 1.0) * 0.30000001192092896));
    }

    private void AddSkinArmorWeaponMultiMeshesToEntity(
      uint teamColor1,
      uint teamColor2,
      bool needBatchedVersion,
      bool forceUseFaceCache = false)
    {
      this.AddSkinMeshesToEntity((int) this._data.EquipmentData.GetSkinMeshesMask(), !needBatchedVersion, forceUseFaceCache);
      this.AddArmorMultiMeshesToAgentEntity(teamColor1, teamColor2);
      int hashCode = this._data.BodyPropertiesData.GetHashCode();
      for (int index = 0; index < 5; ++index)
      {
        if (!this._data.EquipmentData[index].IsEmpty)
        {
          MissionWeapon missionWeapon = new MissionWeapon(this._data.EquipmentData[index].Item, this._data.EquipmentData[index].ItemModifier, this._data.BannerData);
          if (this._data.AddColorRandomnessData)
            missionWeapon.SetRandomGlossMultiplier(hashCode);
          WeaponData weaponData = missionWeapon.GetWeaponData(needBatchedVersion);
          WeaponData ammoWeaponData = missionWeapon.GetAmmoWeaponData(needBatchedVersion);
          this._data.AgentVisuals.AddWeaponToAgentEntity(index, in weaponData, missionWeapon.GetWeaponStatsData(), in ammoWeaponData, missionWeapon.GetAmmoWeaponStatsData(), this._data.GetCachedWeaponEntity((EquipmentIndex) index));
          weaponData.DeinitializeManagedPointers();
          ammoWeaponData.DeinitializeManagedPointers();
        }
      }
      this._data.AgentVisuals.SetWieldedWeaponIndices(this._data.RightWieldedItemIndexData, this._data.LeftWieldedItemIndexData);
      for (int index = 0; index < 5; ++index)
      {
        if (!this._data.EquipmentData[index].IsEmpty && this._data.EquipmentData[index].Item.PrimaryWeapon.IsConsumable)
        {
          short maxDataValue = this._data.EquipmentData[index].Item.PrimaryWeapon.MaxDataValue;
          if (index == this._data.RightWieldedItemIndexData)
            --maxDataValue;
          this._data.AgentVisuals.UpdateQuiverMeshesWithoutAgent(index, (int) maxDataValue);
        }
      }
    }

    private void AddSkinMeshesToEntity(int mask, bool useGPUMorph, bool forceUseFaceCache = false)
    {
      SkinGenerationParams skinParams;
      if (this._data.EquipmentData != null)
      {
        bool isFemale = (double) this._data.BodyPropertiesData.Age >= 14.0 && this._data.SkeletonTypeData == SkeletonType.Female;
        skinParams = new SkinGenerationParams(mask, this._data.EquipmentData.GetUnderwearType(isFemale), (int) this._data.EquipmentData.BodyMeshType, (int) this._data.EquipmentData.HairCoverType, (int) this._data.EquipmentData.BeardCoverType, (int) this._data.EquipmentData.BodyDeformType, this._data.PrepareImmediatelyData, 0.0f, (int) this._data.SkeletonTypeData, this._data.RaceData, this._data.UseTranslucencyData, this._data.UseTesselationData);
      }
      else
        skinParams = new SkinGenerationParams(mask, Equipment.UnderwearTypes.FullUnderwear, 0, 4, 0, 0, this._data.PrepareImmediatelyData, 0.0f, (int) this._data.SkeletonTypeData, this._data.RaceData, this._data.UseTranslucencyData, this._data.UseTesselationData);
      BasicCharacterObject basicCharacterObject = (BasicCharacterObject) null;
      if (this._data.CharacterObjectStringIdData != null)
        basicCharacterObject = MBObjectManager.Instance.GetObject<BasicCharacterObject>(this._data.CharacterObjectStringIdData);
      bool useFaceCache = forceUseFaceCache || basicCharacterObject != null && basicCharacterObject.FaceMeshCache;
      this._data.AgentVisuals.AddSkinMeshes(skinParams, this._data.BodyPropertiesData, useGPUMorph, useFaceCache);
    }

    public void SetFaceGenerationParams(FaceGenerationParams faceGenerationParams)
    {
      this._data.AgentVisuals.SetFaceGenerationParams(faceGenerationParams);
    }

    public void SetVoiceDefinitionIndex(int voiceDefinitionIndex, float voicePitch)
    {
      this._data.AgentVisuals.SetVoiceDefinitionIndex(voiceDefinitionIndex, voicePitch);
    }

    public void StartRhubarbRecord(string path, int soundId)
    {
      this._data.AgentVisuals.StartRhubarbRecord(path, soundId);
    }

    public void SetAgentLodZeroOrMaxExternal(bool makeZero)
    {
      this._data.AgentVisuals.SetAgentLodZeroOrMax(makeZero);
    }

    public void SetAgentLocalSpeed(Vec2 speed) => this._data.AgentVisuals.SetAgentLocalSpeed(speed);

    public void SetLookDirection(Vec3 direction)
    {
      this._data.AgentVisuals.SetLookDirection(direction);
    }

    public void AddArmorMultiMeshesToAgentEntity(uint teamColor1, uint teamColor2)
    {
      Random randomGenerator = (Random) null;
      uint num1;
      uint num2;
      if (this._data.AddColorRandomnessData)
      {
        int hashCode = this._data.BodyPropertiesData.GetHashCode();
        randomGenerator = new Random(hashCode);
        Color color1;
        Color color2;
        AgentVisuals.GetRandomClothingColors(hashCode, Color.FromUint(teamColor1), Color.FromUint(teamColor2), out color1, out color2);
        num1 = color1.ToUnsignedInteger();
        num2 = color2.ToUnsignedInteger();
      }
      else
      {
        num1 = teamColor1;
        num2 = teamColor2;
      }
      for (EquipmentIndex equipmentIndex = EquipmentIndex.HorseHarness; equipmentIndex >= EquipmentIndex.WeaponItemBeginSlot; --equipmentIndex)
      {
        if (equipmentIndex == EquipmentIndex.NumAllWeaponSlots || equipmentIndex == EquipmentIndex.Body || equipmentIndex == EquipmentIndex.Leg || equipmentIndex == EquipmentIndex.Gloves || equipmentIndex == EquipmentIndex.Cape)
        {
          ItemObject itemObject1 = this._data.EquipmentData[(int) equipmentIndex].Item;
          ItemObject itemObject2 = this._data.EquipmentData[(int) equipmentIndex].CosmeticItem ?? itemObject1;
          if (itemObject2 != null)
          {
            bool isFemale = (double) this._data.BodyPropertiesData.Age >= 14.0 && this._data.SkeletonTypeData == SkeletonType.Female;
            bool hasGloves = equipmentIndex == EquipmentIndex.Body && this._data.EquipmentData[EquipmentIndex.Gloves].Item != null;
            MetaMesh multiMesh = this._data.EquipmentData[(int) equipmentIndex].GetMultiMesh(isFemale, hasGloves, true);
            if ((NativeObject) multiMesh != (NativeObject) null)
            {
              if (this._data.AddColorRandomnessData)
                multiMesh.SetGlossMultiplier(AgentVisuals.GetRandomGlossFactor(randomGenerator));
              if (itemObject2.IsUsingTableau && this._data.BannerData != null)
              {
                for (int meshIndex = 0; meshIndex < multiMesh.MeshCount; ++meshIndex)
                {
                  Mesh currentMesh = multiMesh.GetMeshAtIndex(meshIndex);
                  Mesh mesh1 = currentMesh;
                  if ((mesh1 != null ? (!mesh1.HasTag("dont_use_tableau") ? 1 : 0) : 0) != 0)
                  {
                    Mesh mesh2 = currentMesh;
                    if ((mesh2 != null ? (mesh2.HasTag("banner_replacement_mesh") ? 1 : 0) : 0) != 0)
                    {
                      ((BannerVisual) this._data.BannerData.BannerVisual).GetTableauTextureLarge((Action<Texture>) (t => this.ApplyBannerTextureToMesh(currentMesh, t)));
                      currentMesh.ManualInvalidate();
                      break;
                    }
                  }
                  currentMesh.ManualInvalidate();
                }
              }
              else if (itemObject2.IsUsingTeamColor)
              {
                for (int meshIndex = 0; meshIndex < multiMesh.MeshCount; ++meshIndex)
                {
                  Mesh meshAtIndex = multiMesh.GetMeshAtIndex(meshIndex);
                  if (!meshAtIndex.HasTag("no_team_color"))
                  {
                    meshAtIndex.Color = num1;
                    meshAtIndex.Color2 = num2;
                    Material copy = meshAtIndex.GetMaterial().CreateCopy();
                    copy.AddMaterialShaderFlag("use_double_colormap_with_mask_texture", false);
                    meshAtIndex.SetMaterial(copy);
                  }
                  meshAtIndex.ManualInvalidate();
                }
              }
              if (itemObject2.UsingFacegenScaling)
              {
                Skeleton skeleton = this._data.AgentVisuals.GetSkeleton();
                multiMesh.UseHeadBoneFaceGenScaling(skeleton, this._data.MonsterData.HeadLookDirectionBoneIndex, this._data.AgentVisuals.GetFacegenScalingMatrix());
                skeleton.ManualInvalidate();
              }
              this._data.AgentVisuals.AddMultiMesh(multiMesh, MBAgentVisuals.GetBodyMeshIndex(equipmentIndex));
              multiMesh.ManualInvalidate();
            }
          }
        }
      }
    }

    private void ApplyBannerTextureToMesh(Mesh armorMesh, Texture bannerTexture)
    {
      if (!((NativeObject) armorMesh != (NativeObject) null))
        return;
      Material copy = armorMesh.GetMaterial().CreateCopy();
      copy.SetTexture(Material.MBTextureType.DiffuseMap2, bannerTexture);
      uint materialShaderFlagMask = (uint) copy.GetShader().GetMaterialShaderFlagMask("use_tableau_blending");
      ulong shaderFlags = copy.GetShaderFlags();
      copy.SetShaderFlags(shaderFlags | (ulong) materialShaderFlagMask);
      armorMesh.SetMaterial(copy);
    }

    public void MakeRandomVoiceForFacegen()
    {
      GameEntity entity = this._data.AgentVisuals.GetEntity();
      Vec3 origin = entity.Skeleton.GetBoneEntitialFrame(this._data.MonsterData.HeadLookDirectionBoneIndex).origin;
      Vec3 parent = entity.GetFrame().TransformToParent(origin);
      entity.Skeleton.SetAgentActionChannel(1, AgentVisuals.act_command_leftstance_cached);
      SkinVoiceManager.SkinVoiceType[] skinVoiceTypeArray = new SkinVoiceManager.SkinVoiceType[12]
      {
        SkinVoiceManager.VoiceType.Yell,
        SkinVoiceManager.VoiceType.Victory,
        SkinVoiceManager.VoiceType.Charge,
        SkinVoiceManager.VoiceType.Advance,
        SkinVoiceManager.VoiceType.Stop,
        SkinVoiceManager.VoiceType.FallBack,
        SkinVoiceManager.VoiceType.UseLadders,
        SkinVoiceManager.VoiceType.Infantry,
        SkinVoiceManager.VoiceType.FireAtWill,
        SkinVoiceManager.VoiceType.FormLine,
        SkinVoiceManager.VoiceType.FormShieldWall,
        SkinVoiceManager.VoiceType.FormCircle
      };
      this._data.AgentVisuals.MakeVoice(skinVoiceTypeArray[MBRandom.RandomInt(skinVoiceTypeArray.Length)].Index, parent);
    }

    private bool ClearAndAddChangedVisualComponentsOfWeapons(
      Equipment oldEquipment,
      bool needBatchedVersionForMeshes)
    {
      int num1 = 0;
      EquipmentElement equipmentElement;
      for (int index = 0; index <= 3; ++index)
      {
        equipmentElement = oldEquipment[index];
        if (!equipmentElement.IsEqualTo(this._data.EquipmentData[index]))
          ++num1;
      }
      if (num1 > 1)
        return false;
      bool flag1 = false;
      for (int index = 0; index <= 3; ++index)
      {
        equipmentElement = oldEquipment[index];
        if (!equipmentElement.IsEqualTo(this._data.EquipmentData[index]))
        {
          flag1 = true;
          break;
        }
      }
      if (flag1)
      {
        this._data.AgentVisuals.ClearAllWeaponMeshes();
        int num2 = 0;
        int num3 = 0;
        while (num2 < 5)
        {
          equipmentElement = this._data.EquipmentData[num2];
          if (!equipmentElement.IsEmpty)
          {
            MissionWeapon missionWeapon1;
            ref MissionWeapon local1 = ref missionWeapon1;
            equipmentElement = this._data.EquipmentData[num2];
            ItemObject itemObject1 = equipmentElement.Item;
            equipmentElement = this._data.EquipmentData[num2];
            ItemModifier itemModifier1 = equipmentElement.ItemModifier;
            Banner bannerData1 = this._data.BannerData;
            local1 = new MissionWeapon(itemObject1, itemModifier1, bannerData1);
            if (this._data.AddColorRandomnessData)
              missionWeapon1.SetRandomGlossMultiplier(this._data.BodyPropertiesData.GetHashCode());
            equipmentElement = this._data.EquipmentData[num2];
            ItemObject.ItemTypeEnum ammoTypeForItemType = ItemObject.GetAmmoTypeForItemType(WeaponComponentData.GetItemTypeFromWeaponClass(equipmentElement.Item.PrimaryWeapon.WeaponClass));
            bool flag2 = false;
            MissionWeapon missionWeapon2 = new MissionWeapon();
            for (int index = 0; index < 5; ++index)
            {
              equipmentElement = this._data.EquipmentData[index];
              if (!equipmentElement.IsEmpty)
              {
                equipmentElement = this._data.EquipmentData[index];
                if (WeaponComponentData.GetItemTypeFromWeaponClass(equipmentElement.Item.PrimaryWeapon.WeaponClass) == ammoTypeForItemType)
                {
                  flag2 = true;
                  ref MissionWeapon local2 = ref missionWeapon2;
                  equipmentElement = this._data.EquipmentData[index];
                  ItemObject itemObject2 = equipmentElement.Item;
                  equipmentElement = this._data.EquipmentData[index];
                  ItemModifier itemModifier2 = equipmentElement.ItemModifier;
                  Banner bannerData2 = this._data.BannerData;
                  local2 = new MissionWeapon(itemObject2, itemModifier2, bannerData2);
                  if (this._data.AddColorRandomnessData)
                    missionWeapon2.SetRandomGlossMultiplier(this._data.BodyPropertiesData.GetHashCode());
                }
              }
            }
            WeaponData weaponData = missionWeapon1.GetWeaponData(needBatchedVersionForMeshes);
            WeaponData ammoWeaponData = flag2 ? missionWeapon2.GetWeaponData(needBatchedVersionForMeshes) : WeaponData.InvalidWeaponData;
            WeaponStatsData[] weaponStatsData = flag2 ? missionWeapon2.GetWeaponStatsData() : (WeaponStatsData[]) null;
            this._data.AgentVisuals.AddWeaponToAgentEntity(num2, in weaponData, missionWeapon1.GetWeaponStatsData(), in ammoWeaponData, weaponStatsData, (GameEntity) null);
          }
          ++num2;
          ++num3;
        }
        this._data.AgentVisuals.SetWieldedWeaponIndices(this._data.RightWieldedItemIndexData, this._data.LeftWieldedItemIndexData);
      }
      return flag1;
    }

    public void SetClothingColors(uint color1, uint color2)
    {
      this._data.ClothColor1(color1);
      this._data.ClothColor2(color2);
    }

    public void GetClothingColors(out uint color1, out uint color2)
    {
      color1 = this._data.ClothColor1Data;
      color2 = this._data.ClothColor2Data;
    }

    public void SetEntity(GameEntity entity) => this._data.AgentVisuals.SetEntity(entity);
  }
}
